from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
from rest_framework.serializers import ModelSerializer, Serializer

from oplatform.models import ConfigurationData, ConfigurationChannel, Menu, User, ChannelData, MachineCodeData


class ConfigurationSerializer(ModelSerializer):
    status_display = serializers.CharField(source='get_status_display')
    delivery_system_display = serializers.CharField(source='get_delivery_system_display')
    coderate_display = serializers.CharField(source='get_coderate_display')
    tuner_display = serializers.CharField(source='get_tuner_display')
    modulation_display = serializers.CharField(source='get_modulation_display')
    multicast_ipv4_display = serializers.CharField(source='get_multicast_ipv4_display')
    dvr_thread_display = serializers.CharField(source='get_dvr_thread_display')
    scam_support_display = serializers.CharField(source='get_scam_support_display')
    unicast_display = serializers.CharField(source='get_unicast_display')
    psi_tables_filtering_display = serializers.CharField(source='get_psi_tables_filtering_display')
    channels = SerializerMethodField('get__all_channels')

    def get__all_channels(self, instance):
        result = []
        channels = ConfigurationChannel.objects.filter(configurationdata__id=instance.id)
        for channel in channels:
            result.append(ConfigurationChannelSerializer(instance=channel).data)
        return result

    class Meta:
        model = ConfigurationData
        fields = '__all__'


class ChannelSerializer(ModelSerializer):

    class Meta:
        model = ChannelData
        fields = '__all__'


class ConfigurationChannelSerializer(ModelSerializer):

    class Meta:
        model = ConfigurationChannel
        fields = '__all__'


class MachineCodeSerializer(ModelSerializer):
    code = serializers.CharField(write_only=True)

    class Meta:
        model = MachineCodeData
        fields = '__all__'


class MenuSerializer(ModelSerializer):
    sub_menu = SerializerMethodField()

    @staticmethod
    def get_sub_menu(obj):
        serializer = MenuSerializer(instance=Menu.objects.filter(father=obj), many=True)
        return serializer.data

    class Meta:
        model = Menu
        fields = '__all__'


class MenuTreeSerializer(MenuSerializer):
    sub_menu = SerializerMethodField(read_only=True)

    def to_representation(self, instance):
        """
        判断是否为叶子节点，为返回结果添加叶子节点属性leaf_node
        :param instance:
        :return:
        """
        ret = super(MenuTreeSerializer, self).to_representation(instance)
        # 返回一个数组
        sub = ret.get('sub_menu')
        ret['leaf_node'] = True if len(sub) == 0 else False
        return ret

    @staticmethod
    def get_sub_menu(obj):
        serializer = MenuTreeSerializer(instance=Menu.objects.filter(father=obj), many=True)
        return serializer.data


class UserSerializer(ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = '__all__'
